package com.example.controller;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.entity.Count;
import com.example.entity.LargeEntity;
import com.example.mapper.CountMapper;
import com.example.units.ApiResponse;
import com.example.units.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.ListUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import com.example.service.CountService;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import static org.apache.commons.lang3.SerializationUtils.deserialize;
import static org.springframework.util.SerializationUtils.serialize;

@Slf4j
@RestController

public class CountController {
@Autowired
    CountMapper mapper;
@Autowired
MongoTemplate mongoTemplate;
@Autowired
RedisTemplate redisTemplate;
String countCollection = "count";
//@GetMapping("/redisTest")
//public ApiResponse getCount(){
//
//        List<LargeEntity> mergedList = new ArrayList<>();
//        int shardIndex = 0;
//
//        while (true) {
//            String shardKey = "users:chunk_" + shardIndex++;
//            List<LargeEntity> data = (List<LargeEntity>) redisTemplate.opsForValue().get(shardKey);
//
//            if (data == null) break;
//            deserialize(data)
//
//            mergedList.addAll(data);
//        }
//        if(mergedList.size() != 0){
//            return ApiResponse.success(mergedList);
//        }
//
//
//    List<LargeEntity> largeEntities = LargeEntity.generate71MBList();
//    int chunkSize=100;
//    List<List<LargeEntity>> lists= ListUtils.partition(largeEntities, chunkSize);
//    for (int i = 0; i < lists.size(); i++) {
//        String chunkKey = "users:chunk_" + i;
//        List<LargeEntity> chunk = new ArrayList<>(lists.get(i));
//        byte[] serialize = serialize(chunk);// 转换为可序列化的ArrayList
//        redisTemplate.opsForValue().set(chunkKey, serialize);
//
//    }
////    redisTemplate.opsForValue().set("largeEntities", largeEntities,3, TimeUnit.HOURS);
//    return ApiResponse.success(largeEntities);
//}
List<JSONObject> compStages( JSONObject jsonObject) {
    List<JSONObject> stagesList=new ArrayList<>();

    if(null==jsonObject.getInteger("stages")) {
        return null;
    }else{
        Double amount = jsonObject.getDouble("amount");
        Integer stages1 = jsonObject.getInteger("stages");
        List<String> stages = DateUtils.generateInstallmentDates(jsonObject.getInteger("stages"),jsonObject.getString("firstPaymentDate"));
        DecimalFormat df = new DecimalFormat("#.00"); // 或 "0.00"
        String oneStagesCount=df.format(amount/stages1);

        for(String stage:stages){
            JSONObject stageObj=new JSONObject();
            stageObj.put("stage",stage);
            stageObj.put("amount",oneStagesCount);
            stageObj.put("isBack",false);
            stagesList.add(stageObj);
        }

    }
    return  stagesList;
}
    @PostMapping("/saveCount")
    public ApiResponse save(@RequestBody String count) {
        JSONObject jsonObject = JSONObject.parseObject(count);
        System.out.println("saveCount--->jsonObject = " + jsonObject);
        if(jsonObject.getString("id") == null){
            jsonObject.put("id",UUID.randomUUID().toString());
            List<JSONObject> jsonObjects = compStages(jsonObject);
            // 从JSON对象获取数据
            BigDecimal reFund = jsonObject.getBigDecimal("reFund");
            BigDecimal amount = jsonObject.getBigDecimal("amount");
            String date = jsonObject.getString("date");  // 移动到if外部以便使用

// 当有退款金额时计算回本日期
            if(reFund!=null&&reFund.compareTo(BigDecimal.ZERO) > 0) {
                // 计算回本所需天数（金额差取整）
               int days= amount.divide(reFund, 0, RoundingMode.UP).intValue();
                // 解析原始日期（假设格式为yyyy-MM-dd）
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                LocalDateTime originalDate = LocalDateTime.parse(date, formatter);

                // 添加天数计算回本日期
                LocalDateTime reFundDateValue = originalDate.plusDays(days);

                // 格式化为字符串并存入JSON对象
                jsonObject.put("reFundDate", reFundDateValue.format(formatter));
            }
            if(jsonObjects != null && jsonObjects.size() > 0) {
                jsonObject.put("stagesList",jsonObjects);
            }
            mongoTemplate.insert(jsonObject, countCollection);

        }else {
            Update update = new Update();
            update.set("id", jsonObject.getString("id"));
            update.set("amount", jsonObject.getString("amount"));
            update.set("category", jsonObject.getString("category"));
            update.set("countType", jsonObject.getString("countType"));
            List<JSONObject> jsonObjects= new ArrayList<>();
            if(!jsonObject.containsKey("stagesList")){
                jsonObjects= compStages(jsonObject);

            }else{
                jsonObjects=jsonObject.getJSONArray("stagesList").toJavaList(JSONObject.class);
            }
            if(jsonObjects != null && jsonObjects.size() > 0) {
                update.set("stages",jsonObject.getIntValue("stages"));
                update.set("stagesList",jsonObjects);
            }
Query query = new Query(Criteria.where("id").is(jsonObject.getString("id")));
            mongoTemplate.updateFirst(query,update,countCollection);

        }
        return ApiResponse.success("保存成功");
    }
    @GetMapping("getCount/{email}")
    public ApiResponse getCount(@PathVariable String email) {
        Query query = new Query();
        query.addCriteria(Criteria.where("creater").is(email));
        query.addCriteria(Criteria.where("del").ne(1));
        List<JSONObject> jsonObjects = mongoTemplate.find(query, JSONObject.class, countCollection);
        return ApiResponse.successData(jsonObjects);
    } @PostMapping("/reset")
    public ApiResponse reset(@RequestBody String body) {
    try{
        JSONObject jsonObject = JSONObject.parseObject(body);
        String creater = jsonObject.getString("creater");
        List<JSONObject> countList = mongoTemplate.find(new Query().addCriteria(Criteria.where("creater").is(creater)), JSONObject.class, countCollection);
        countList.stream().forEach(count->{
           Update update = new Update();
           update.set("del",1);
           mongoTemplate.updateFirst(new Query().addCriteria(Criteria.where("id").is(count.getString("id"))), update, countCollection);
        });
    } catch (Exception e) {
        e.printStackTrace();
        return ApiResponse.failure(e.getMessage());
    }
           return ApiResponse.success();
    }
    String assetTypes="assetTypes";
    @PostMapping("/getAssetType")
    public ApiResponse getAssetType(@RequestBody String body) {
    try{
        JSONObject jsonObject = JSONObject.parseObject(body);
        String creater = jsonObject.getString("creater");
        JSONObject all = mongoTemplate.findOne(new Query().addCriteria(Criteria.where("creater").is(creater)),JSONObject.class, assetTypes);
        List<JSONObject> assetTypes=all.getJSONArray("assetTypes").toJavaList(JSONObject.class);
        return ApiResponse.successData(assetTypes);
    } catch (Exception e) {
        e.printStackTrace();
        return ApiResponse.failure(e.getMessage());
    }

    } @PostMapping("/saveAssetType")
    public ApiResponse saveAssetType(@RequestBody String body) {
    try{
       JSONObject jsonObject = JSONObject.parseObject(body);
       String creater = jsonObject.getString("creater");
        JSONArray assetTypes1 = jsonObject.getJSONArray("assetTypes");
        List<JSONObject> javaList = assetTypes1.toJavaList(JSONObject.class);

        JSONObject creater1 = mongoTemplate.findOne(new Query().addCriteria(Criteria.where("creater").is(creater)), JSONObject.class, assetTypes);
        if(creater1==null){
            creater1=new JSONObject();
            creater1.put("creater",creater);
            creater1.put("assetTypes",javaList);
            mongoTemplate.insert(creater1,assetTypes);
        }else{
            creater1.put("assetTypes",javaList);
            mongoTemplate.save(creater1,assetTypes);
        }
        return ApiResponse.success();
    } catch (Exception e) {
        e.printStackTrace();
        return ApiResponse.failure(e.getMessage());
    }

    }
    @PostMapping("/deleteCount")
    public ApiResponse deleteCount(@RequestBody JSONObject jsonObject) {
        try {
            Query query = new Query();
            query.addCriteria(Criteria.where("id").is(jsonObject.getString("id")));
            Update update = new Update();
            update.set("del",1);
            mongoTemplate.upsert(query,update,countCollection);
            return ApiResponse.success("删除成功");
        }catch (Exception e){
            e.printStackTrace();
            return ApiResponse.failure(e.getMessage());
        }

    }
     /*
     *
     * 更新还款记录
     *
     * */
    @PostMapping("/updateStage")
    public ApiResponse updateStage(@RequestBody JSONObject jsonObject) {
        log.info("updateStage--->jsonObject = " + jsonObject);
        String id = jsonObject.getString("recordId");
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(id));
        JSONObject one = mongoTemplate.findOne(query, JSONObject.class, countCollection);
        if(one==null){
            return  ApiResponse.failure("还款记录更新失败");

        }
        com.alibaba.fastjson2.JSONArray stagesList1 = one.getJSONArray("stagesList");
        List<JSONObject> stagesList= stagesList1.toJavaList(JSONObject.class);
        stagesList.stream().forEach(stage->{
            if(stage.getString("stage").equals(jsonObject.getJSONObject("stage").getString("stage"))){

                stage.put("isBack",true);
                stage.put("backTime",jsonObject.getJSONObject("stage").getString("backTime"));
            }
        });
        Update update = new Update();
        update.set("stagesList",stagesList);
        mongoTemplate.updateFirst(new Query().addCriteria(Criteria.where("id").is(id)),update,countCollection);
        return ApiResponse.success();
    }

}